Passed
Pull Request — master (#3)
by Tito
03:27
created

gulp-utils.js ➔ generateContentTasks   F

Complexity

Conditions 16

Size

Total Lines 92
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 60
dl 0
loc 92
rs 2.4
c 0
b 0
f 0
cc 16

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gulp-utils.js ➔ generateContentTasks often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
const utils = require("./utils.js");
2
const gulp = require("gulp");
3
const zip = require("gulp-zip");
4
const vinylPaths = require("vinyl-paths");
5
const del = require("del");
6
const composer = require("gulp-composer");
7
const fs = require("fs");
8
9
/**
10
 * Main configuration
11
 *
12
 * @type {{defaultTasks: string[], releaseDir: string, wwwDir: string, watchInterval: number, useVersions: boolean}}
13
 */
14
const config = {
15
    "defaultTasks": ["release"],
16
    "releaseDir": "./releases",
17
    "wwwDir": "/.tmp/www",
18
    "watchInterval": 500,
19
    "useVersions": true
20
};
21
22
/**
23
 * Base tasks for every directory (to be cloned using getBaseTasks)
24
 *
25
 * @type {{release: Array, clean: Array, copy: Array, watch: Array}}
26
 */
27
const baseDirSt = {
28
    "release": [],
29
    "clean": [],
30
    "copy": [],
31
    "watch": []
32
};
33
34
/**
35
 * Sets the configuration from a data object, overwriting it where possible
36
 *
37
 * @param data
38
 */
39
function setConfigurationFromData(data) {
40
    "use strict";
41
    if (data.hasOwnProperty("defaultTasks")) {
42
        config.defaultTasks = data.defaultTasks;
43
    }
44
    if (data.hasOwnProperty("releaseDir")) {
45
        config.releaseDir = data.releaseDir;
46
    }
47
    if (data.hasOwnProperty("wwwDir")) {
48
        config.wwwDir = data.wwwDir;
49
    }
50
    if (data.hasOwnProperty("watchInterval")) {
51
        config.watchInterval = data.watchInterval;
52
    }
53
    if (data.hasOwnProperty("useVersions")) {
54
        config.useVersions = data.useVersions;
55
    }
56
}
57
58
/**
59
 * Clones the base task set
60
 *
61
 * @returns {Object}
62
 */
63
function getBaseTasks() {
64
    "use strict";
65
    return utils.cloneObject(baseDirSt);
66
}
67
68
/**
69
 * Clones only the web tasks
70
 *
71
 * @returns {Object}
72
 */
73
function getBaseWebTasks() {
74
    "use strict";
75
    const webTasks = utils.cloneObject(baseDirSt);
76
    delete webTasks.release;
77
    return webTasks;
78
}
79
80
/**
81
 * Generates a full task set based on the baseDirSt object and the baseTask given
82
 *
83
 * @param {string}  baseTask
84
 * @param {Object}  taskSet               Optional to populate an existing variable
85
 * @param {boolean} generateReleaseTasks  Generate release tasks or not
86
 * @param {boolean} generateWebTasks      Generate web tasks or not
87
 *
88
 * @returns {Array}
89
 */
90
function generateTaskSet(baseTask, taskSet, generateReleaseTasks, generateWebTasks) {
91
    "use strict";
92
    const tasks =
93
            (taskSet === null
94
        ? getBaseTasks()
95
        : null);
96
    let destination =
97
            (taskSet === null
98
        ? tasks
99
        : taskSet);
100
101
    if (generateReleaseTasks) {
102
        destination.release.push("release:" + baseTask);
103
    } else {
104
        delete destination.release;
105
    }
106
    if (generateWebTasks) {
107
        destination.clean.push("clean:" + baseTask);
108
        destination.copy.push("copy:" + baseTask);
109
        destination.watch.push("watch:" + baseTask);
110
    } else {
111
        delete destination.clean;
112
        delete destination.copy;
113
        delete destination.watch;
114
    }
115
    return destination;
116
}
117
118
/**
119
 * Creates the gulp tasks given a base task and its dependencies, both following the base task structure
120
 *
121
 * @param {string}          baseTask
122
 * @param {Object}          dependencies
123
 * @param {Object|boolean}  tasks         Object with tasks to generate.  If false it generates the default set
124
 */
125
function createGulpTasks(baseTask, dependencies, tasks) {
126
    "use strict";
127
    if (tasks === false || tasks.hasOwnProperty("release")) {
128
        gulp.task("release:" + baseTask, gulp.parallel(dependencies.release));
129
    }
130
    if (tasks === false || tasks.hasOwnProperty("clean")) {
131
        gulp.task("clean:" + baseTask, gulp.parallel(dependencies.clean));
132
    }
133
    if (tasks === false || tasks.hasOwnProperty("copy")) {
134
        gulp.task("copy:" + baseTask, gulp.parallel(dependencies.copy));
135
    }
136
    if (tasks === false || tasks.hasOwnProperty("watch")) {
137
        gulp.task("watch:" + baseTask, gulp.parallel(dependencies.watch));
138
    }
139
}
140
141
/**
142
 * Generates generic tasks for a given directory and returns them with their directories
143
 *
144
 * @param {string} mainDir    Main directory where tasks reside (subfolders are getting their own tasks)
145
 * @param {string} baseTask   Base task of the main directory (to be created with dependency on the sub directory tasks)
146
 *
147
 * @returns {Object}  Collection of tasks and collection of directories, each with its own tasks
148
 */
149
function generateDirTasks(mainDir, baseTask) {
150
    "use strict";
151
    const mainTasks = getBaseTasks();
152
    const directories = [];
153
    utils.getFilesByType(mainDir, "directory").forEach(function (dir) {
154
        const dirTasks = generateTaskSet(baseTask + ":" + dir, null, true, true);
155
        generateTaskSet(baseTask + ":" + dir, mainTasks, true, true);
156
        directories.push({"directory": dir, tasks: dirTasks});
157
    });
158
    return {"tasks": mainTasks, "directories": directories};
159
}
160
161
/**
162
 * Generates and creates the actual gulp tasks for a given directory, considering it an actual extension
163
 *
164
 * @param {string} dir                    Directory where content tasks are to be generated
165
 * @param {Array}  extraSources           Other source directories to include
166
 * @param {string} extensionName          Extension name
167
 * @param {string} baseTask               Base task name of this directory
168
 * @param {string} destinationWebDir      Directory where this package belongs in the website
169
 * @param {string} destinationReleaseDir  Directory where the release package will be moved to
170
 * @param {string} zipName                Zip name to provide to the release package
171
 *
172
 * @returns {Object}  Generated tasks dependent of the main task
173
 */
174
function generateContentTasks(dir, extraSources, extensionName, baseTask, destinationWebDir, destinationReleaseDir, zipName) {
175
    "use strict";
176
    // Checks which tasks must be generated.  If dirs are omitted, tasks are too
177
    const executeWebTasks = destinationWebDir !== "";
178
    const executeReleaseTasks = destinationReleaseDir !== "";
179
180
    // Get out of here if no directories are provided
181
    if (!executeWebTasks && !executeReleaseTasks) {
182
        return {};
183
    }
184
185
    const releaseTasks = ["release-do:" + baseTask];
186
    const copyTasks = ["copy-do:" + baseTask];
187
    const watchTasks = ["watch-main:" + baseTask];
188
    const composerExists = fs.existsSync(dir + "/composer.json");
189
    const sources = [dir + "/**"].concat(extraSources);
190
191
    if (composerExists) {
192
        gulp.task("composer:" + baseTask, function () {
193
            return composer({"working-dir": dir});
194
        });
195
        releaseTasks.unshift("composer:" + baseTask);
196
        copyTasks.unshift("composer:" + baseTask);
197
        watchTasks.unshift("watch-composer:" + baseTask);
198
    }
199
200
    if (executeReleaseTasks) {
201
        // Release tasks
202
        const releaseFunction = function () {
203
            const versionNumber =
204
                    config.useVersions === true
205
                ? utils.getManifestVersion(dir + "/" + extensionName + ".xml")
206
                : "";
207
            const versionName = (
208
                versionNumber !== ""
209
                    ? "-v" + versionNumber
210
                    : ""
211
            );
212
            return gulp.src(sources)
213
                .pipe(zip(zipName + versionName + ".zip"))
214
                .pipe(gulp.dest(config.releaseDir + "/" + destinationReleaseDir));
215
216
        };
217
        if (composerExists) {
218
            gulp.task("release-do:" + baseTask, releaseFunction);
219
            gulp.task("release:" + baseTask, gulp.parallel(releaseTasks));
220
        } else {
221
            gulp.task("release:" + baseTask, releaseFunction);
222
        }
223
    }
224
225
    if (executeWebTasks) {
226
        // Clean task
227
        gulp.task("clean:" + baseTask, function () {
228
            return gulp.src(config.wwwDir + "/" + destinationWebDir, {"allowEmpty": true})
229
                .pipe(vinylPaths(function (paths) {
230
                    del.sync(paths, {"force": true});
231
                    return Promise.resolve();
232
                }));
233
        });
234
235
        // Copy tasks
236
        gulp.task("copy-do:" + baseTask, gulp.series("clean:" + baseTask, function () {
237
            return gulp.src(sources)
238
                .pipe(gulp.dest(config.wwwDir + "/" + destinationWebDir));
239
        }));
240
        gulp.task("copy:" + baseTask, gulp.series(copyTasks));
241
242
        // Watch tasks
243
        const watchFunction = function () {
244
            return gulp.watch(sources,
245
                    {interval: config.watchInterval},
246
                    gulp.series("copy-do:" + baseTask));
247
        };
248
249
        if (composerExists) {
250
            gulp.task("watch-composer:" + baseTask, function () {
251
                return gulp.watch(
252
                    [dir + "/composer.json", dir + "/composer.lock"],
253
                    {interval: config.watchInterval},
254
                    gulp.series("composer:" + baseTask)
255
                );
256
            });
257
            gulp.task("watch-main:" + baseTask, watchFunction);
258
            gulp.task("watch:" + baseTask, gulp.parallel(watchTasks));
259
        } else {
260
            gulp.task("watch:" + baseTask, watchFunction);
261
        }
262
    }
263
264
    return generateTaskSet(baseTask, null, executeReleaseTasks, executeWebTasks);
265
}
266
267
exports.config = config;
268
exports.baseDirSt = baseDirSt;
269
exports.setConfigurationFromData = setConfigurationFromData;
270
exports.getBaseTasks = getBaseTasks;
271
exports.getBaseWebTasks = getBaseWebTasks;
272
exports.generateDirTasks = generateDirTasks;
273
exports.generateContentTasks = generateContentTasks;
274
exports.createGulpTasks = createGulpTasks;